import { sum } from "lodash";
import { useMemo } from "react";
import { ColFixeds, IColumn } from "../VTable";
import { defaultTableCellWidth, emptyAry } from "./const";

export enum EDirection {
  UP = "ArrowUp",
  DOWN = "ArrowDown",
  LEFT = "ArrowLeft",
  RIGHT = "ArrowRight",
}

/** 键盘key转移动方向 */
export const keyboardKey2direction = {
  ArrowUp: EDirection.UP,
  ArrowDown: EDirection.DOWN,
  ArrowLeft: EDirection.LEFT,
  ArrowRight: EDirection.RIGHT,
};

/**
 * 移动坐标
 * @param pos 坐标
 * @param direction 移动方向
 * @param xInterval x索引区间
 * @param yInterval y索引区间
 * @returns
 */
export function moveXy(
  pos: [number, number],
  direction: EDirection,
  xInterval: [number, number],
  yInterval: [number, number]
): [number, number] {
  const [x, y] = pos;
  if (direction === EDirection.UP) {
    if (x === xInterval[0]) return pos;
    return [x - 1, y];
  } else if (direction === EDirection.DOWN) {
    if (x === xInterval[1]) return pos;
    return [x + 1, y];
  } else if (direction === EDirection.LEFT) {
    if (y === yInterval[0]) return pos;
    return [x, y - 1];
  } else if (direction === EDirection.RIGHT) {
    if (y === yInterval[1]) return pos;
    return [x, y + 1];
  } else {
    return pos;
  }
}

/**
 * 计算树的深度
 * @param node
 * @returns
 */
export function calcTreeDepth(node: any) {
  if (!node.children || node.children.length === 0) {
    return 1;
  } else {
    const childDepths = node.children.map(calcTreeDepth);
    return 1 + Math.max(...childDepths);
  }
}

/**
 * 为表头数据添加colSpan
 * @param data
 * @returns
 */
export function addColSpan(
  data: IColumn<any>
): IColumn & { thColSpan: number } {
  const cloneData = { ...data };
  (cloneData as any).thColSpan =
    sum(
      (cloneData.children || []).map((child) => addColSpan(child).thColSpan)
    ) || 1;
  return cloneData as any;
}

/**
 * 需要渲染的表头深度
 * @param data
 * @returns
 */
export function theadDoms(
  cols: IColumn<any>[]
): (IColumn & { thRowSpan: number; thColSpan: number })[][] {
  const data = cols.map(addColSpan);
  const trs: IColumn<any>[][] = [];
  const rowCount = Math.max(...data.map(calcTreeDepth));
  const travel = (data: IColumn<any>[], level: number) => {
    trs[level] = trs[level] || [];
    data.forEach((col: any) => {
      if (col.children) {
        trs[level].push(col);
        travel(col.children || emptyAry, level + 1);
      } else {
        col.thRowSpan = rowCount - level;
        trs[level].push(col);
      }
    });
  };
  travel(data, 0);
  return trs as any;
}

/**
 * 获取固定列配置
 * @param cols
 * @returns
 */
export function useColFixed(cols: IColumn[]) {
  const res = useMemo(() => {
    const colFixed: ColFixeds = {};
    const leftFixed: IColumn[] = [];
    const rightFixed: IColumn[] = [];

    let prevColIsFixed = false;
    let fixedFirst: Record<string, boolean> = {};
    cols.forEach((col) => {
      if (col.fixed === "right") {
        rightFixed.unshift(col);
        fixedFirst[col.key] = !prevColIsFixed;
      }
      prevColIsFixed = col.fixed === "right";
    });
    let rightOffset = 0;
    rightFixed.forEach((col) => {
      colFixed[col.key] = {
        isRight: true,
        offset: rightOffset,
        first: fixedFirst[col.key],
      };
      rightOffset += col.width || defaultTableCellWidth;
    });
    let leftOffset = 0;
    prevColIsFixed = false;
    [...cols].reverse().forEach((col) => {
      if (col.fixed === "left") {
        leftFixed.unshift(col);
        fixedFirst[col.key] = !prevColIsFixed;
      }
      prevColIsFixed = col.fixed === "left";
    });
    leftFixed.forEach((col) => {
      colFixed[col.key] = {
        isLeft: true,
        offset: leftOffset,
        first: fixedFirst[col.key],
      };
      leftOffset += col.width || defaultTableCellWidth;
    });

    return colFixed;
  }, [cols]);
  return res;
}
